#!/bin/bash

# 对用户输入的名称进行校验
while :; do
  # 如果用户未输入任何字符或输入空字符串，则采用默认名称myapp
  read -p "请输入项目名称（默认为myapp）： " projectName
  if [ -z "$projectName" ]; then
    projectName="myapp"
    break
  fi

  # 校验用户输入是否满足规则
  if [[ "$projectName" =~ ^[a-zA-Z][a-zA-Z0-9]{2,}$ ]]; then
    break
  else
    echo "项目名称 "$projectName" 不符合规则，仅允许英文字母开头，由大小写英文字母和数字组成，长度最少为3。"
  fi
done

# 循环结束后，可以使用projectName变量
echo "选定的项目名称是: $projectName"

# 创建项目根目录及其子目录
mkdir -p $projectName/cli $projectName/server $projectName/internal/config $projectName/internal/logic $projectName/internal/dao $projectName/internal/service $projectName/internal/presentation $projectName/third_party

# 创建README和许可证文件
touch $projectName/README.md
touch $projectName/LICENSE

# 创建主程序文件
cat <<EOF > $projectName/cli/main.go
package main

import "fmt"

func main() {
    // 这里是程序的入口点
    // 编写你的程序逻辑
    fmt.Println("Hello CLI World!")
}
EOF

cat <<EOF > $projectName/server/main.go
package main

import "fmt"

func main() {
    // 这里是程序的入口点
    // 编写你的程序逻辑
    fmt.Println("Hello Server World!")
}
EOF

# 创建配置文件
cat <<EOF > $projectName/internal/config/config.go
package config

// 这里是配置相关的代码
// 例如，加载和解析配置文件
EOF

# 创建主要业务逻辑文件
cat <<EOF > $projectName/internal/logic/logic.go
package logic

// 这里是应用程序的核心业务逻辑
EOF

# 创建数据访问层文件
cat <<EOF > $projectName/internal/dao/dao.go
package dao

// 这里是数据访问层代码
// 例如，与数据库或外部API的交互
EOF

# 创建服务层文件
cat <<EOF > $projectName/internal/service/service.go
package service

// 这里是业务逻辑的服务层
// 可能包含一些跨领域逻辑
EOF

# 创建输出格式化文件
cat <<EOF > $projectName/internal/presentation/output.go
package presentation

// 这里是应用程序的输出逻辑
// 例如，命令行界面的打印和格式化
EOF

# 创建第三方依赖的README文件
echo "第三方依赖信息" > $projectName/third_party/README.md

# 确保脚本在正确的目录执行
SCRIPT_DIR=$(dirname "$0")
cd "$SCRIPT_DIR" || exit

# 检查项目目录是否存在，如果不存在则创建
if [ ! -d "$projectName" ]; then
  echo "Creating $projectName directory..."
  mkdir $projectName
fi

# 进入项目目录
cd $projectName || exit

# 先输出DIST_NAME := 及以前的文本
cat << 'EOF' > Makefile
# 定义目录和路径变量
SERVERMAIN := server
CLIMAIN := cli
DIST_DIR := dist
EOF

# 向Makefile中追加项目名称作为DIST_NAME的定义
echo "DIST_NAME := $projectName" >> Makefile

# 创建Makefile
cat << 'EOF' >> Makefile
GOOS_LIST := linux darwin windows
GOARCH_LIST := amd64 386 arm arm64
UPX_BIN := upx

# 目标1：清理构建目录
.PHONY: clean
clean:
	@rm -rf $(DIST_DIR)

# 目标2：枚举GOOS和GOARCH的组合生成可执行程序
.PHONY: build
build: clean
	@mkdir -p $(DIST_DIR)
	@for GOOS in $(GOOS_LIST); do \
		for GOARCH in $(GOARCH_LIST); do \
			if [ "$$GOOS" = "windows" ]; then \
				GOOS=$$GOOS GOARCH=$$GOARCH go build -o $(DIST_DIR)/$$GOOS/$$GOARCH/$(DIST_NAME)-cli.exe $(CLIMAIN)/main.go; \
				GOOS=$$GOOS GOARCH=$$GOARCH go build -o $(DIST_DIR)/$$GOOS/$$GOARCH/$(DIST_NAME)-server.exe $(SERVERMAIN)/main.go; \
			elif [ "$$GOOS" = "darwin" ]; then \
				if [ "$$GOARCH" = "amd64" ] || [ "$$GOARCH" = "arm64" ]; then \
					GOOS=$$GOOS GOARCH=$$GOARCH go build -o $(DIST_DIR)/$$GOOS/$$GOARCH/$(DIST_NAME)-cli $(CLIMAIN)/main.go; \
					GOOS=$$GOOS GOARCH=$$GOARCH go build -o $(DIST_DIR)/$$GOOS/$$GOARCH/$(DIST_NAME)-server $(SERVERMAIN)/main.go; \
				fi; \
			else \
				GOOS=$$GOOS GOARCH=$$GOARCH go build -o $(DIST_DIR)/$$GOOS/$$GOARCH/$(DIST_NAME)-cli $(CLIMAIN)/main.go; \
				GOOS=$$GOOS GOARCH=$$GOARCH go build -o $(DIST_DIR)/$$GOOS/$$GOARCH/$(DIST_NAME)-server $(SERVERMAIN)/main.go; \
			fi; \
		done; \
	done

# 检查UPX是否存在
check-upx:
ifeq (,$(shell which $(UPX_BIN)))
	@echo "Error: 未找到UPX。请安装UPX以继续进行压缩操作。"
	@exit 1
endif

# 目标3：用 upx 压缩这些可执行程序（修改后的）
.PHONY: compress
compress: check-upx build
	@for GOOS in $(GOOS_LIST); do \
		for GOARCH in $(GOARCH_LIST); do \
			if [ "$$GOOS" = "windows" ]; then \
				$(UPX_BIN) --best $(DIST_DIR)/$$GOOS/$$GOARCH/$(DIST_NAME)-server.exe; \
				$(UPX_BIN) --best $(DIST_DIR)/$$GOOS/$$GOARCH/$(DIST_NAME)-cli.exe; \
			elif [ "$$GOOS" = "darwin" ]; then \
				if [ "$$GOARCH" = "amd64" ] || [ "$$GOARCH" = "arm64" ]; then \
					$(UPX_BIN) --best $(DIST_DIR)/$$GOOS/$$GOARCH/$(DIST_NAME)-server; \
					$(UPX_BIN) --best $(DIST_DIR)/$$GOOS/$$GOARCH/$(DIST_NAME)-cli; \
				fi; \
			else \
				$(UPX_BIN) --best $(DIST_DIR)/$$GOOS/$$GOARCH/$(DIST_NAME)-server; \
				$(UPX_BIN) --best $(DIST_DIR)/$$GOOS/$$GOARCH/$(DIST_NAME)-cli; \
			fi; \
		done; \
	done
EOF

# 输出完成信息
echo "Makefile has been created in $projectName directory."

# 初始化模块
go mod init gitee.com/imlijinting/"$projectName" && go mod tidy

# 输出完成信息
echo "目录和文件已创建完毕。"